﻿/*======================================
作者：洞庭夕照
创建：2017.8.18
网站：www.ninesky.cn
      mzwhj.cnblogs.com
代码：git.oschina.net/ninesky/Ninesky
版本：v1.0.0.0
======================================
*/
using System;
using Ninesky.IService;
using System.Threading.Tasks;
using Ninesky.Models;
using System.Linq.Expressions;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Ninesky.DBLibrary;

namespace Ninesky.Service
{
    /// <summary>
    /// 服务基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseService<T>:IBaseService<T> where T:class
    {
        public NsDbContext NsDbContext { get; set; }

        public BaseService(NsDbContext nsDbContext)
        {
            NsDbContext = nsDbContext;
        }

        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="isSave">是否立即保存[可选]</param>
        /// <returns>操作结果
        /// OperationResult.Succeed：操作是否完成，当isSave=false仅表示操作完成并未实际保存到数据库；
        /// OperationResult.Code：无返回值；
        /// OperationResult.Message：操作结果的文本提示；
        /// OperationResult.Data：无返回值。
        /// </returns>
        public virtual async Task<OperationResult> AddAsync(T entity, bool isSave = true)
        {
            OperationResult opsResult = new OperationResult();
            await NsDbContext.Set<T>().AddAsync(entity);
            if (isSave)
            {
                opsResult.Succeed = NsDbContext.SaveChanges() > 0;
                opsResult.Message = opsResult.Succeed ? "添加成功" : "添加失败";
            }
            else
            {
                opsResult.Succeed = true;
                opsResult.Message = "已添加到新增队列";
            }
            return opsResult;
        }


        /// <summary>
        /// 记录数
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns>记录数</returns>
        public virtual async Task<int> CountAsync(Expression<Func<T, bool>> predicate)
        {
            return await NsDbContext.Set<T>().CountAsync(predicate);
        }


        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns>是否存在</returns>
        public virtual async Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate)
        {
            return await NsDbContext.Set<T>().AnyAsync(predicate);
        }


        /// <summary>
        /// 查询单个实体
        /// </summary>
        /// <param name="keyValues">主键</param>
        /// <returns>实体</returns>
        public virtual async Task<T> FindAsync(int id)
        {
            return await NsDbContext.Set<T>().FindAsync(id);
        }

        /// <summary>
        /// 查询单个实体
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns>实体</returns>
        public virtual async Task<T> FindAsync(Expression<Func<T, bool>> predicate)
        {
            return await NsDbContext.Set<T>().SingleOrDefaultAsync(predicate);
        }

        /// <summary>
        /// 查询全部实体列表
        /// </summary>
        /// <returns>实体列表</returns>
        public virtual async Task<IQueryable<T>> FindAllAsync()
        {
            IQueryable<T> result = NsDbContext.Set<T>();
            return await Task.FromResult(result);
        }

        /// <summary>
        /// 查询实体列表
        /// </summary>
        /// <param name="number">显示数量[小于等于0-不启用]</param>
        /// <typeparam name="TKey">排序字段类型</typeparam>
        /// <param name="predicate">查询条件</param>
        /// <param name="keySelector">排序字段属性表达式</param>
        /// <param name="isAsc">是否正序</param>
        /// <returns>实体列表</returns>
        public virtual async Task<IQueryable<T>> FindListAsync<TKey>(int number, Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> keySelector, bool isAsc)
        {
            var entityList = NsDbContext.Set<T>().AsNoTracking<T>().Where(predicate);
            if (isAsc) entityList = entityList.OrderBy(keySelector);
            else entityList.OrderByDescending(keySelector);
            if (number > 0) entityList = entityList.Take(number);
            return await Task.FromResult(entityList);
        }


        /// <summary>
        /// 查询实体分页数据
        /// </summary>
        /// <typeparam name="TKey">排序属性类型</typeparam>
        /// <param name="predicate">查询条件</param>
        /// <param name="keySelector">排序字段属性表达式</param>
        /// <param name="isAsc">是否正序</param>
        /// <param name="paging">分页数据</param>
        /// <returns>分页数据</returns>
        public virtual async Task<Paging<T>> FindPagingAsync<TKey>(Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> keySelector, bool isAsc, Paging<T> paging)
        {
            var entityList = NsDbContext.Set<T>().AsNoTracking<T>().Where(predicate);
            paging.Total = await entityList.CountAsync();
            if (isAsc) entityList = entityList.OrderBy(keySelector);
            else entityList.OrderByDescending(keySelector);
            paging.Entities = await entityList.Skip((paging.PageIndex - 1) * paging.PageSize).Take(paging.PageSize).ToListAsync();
            return paging;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="isSave">是否立即保存</param>
        /// <returns>是否删除成功[isSave=true时有效]</returns>
        public virtual async Task<OperationResult> RemoveAsync(T entity, bool isSave = true)
        {
            OperationResult opsResult = new OperationResult();
            NsDbContext.Set<T>().Remove(entity);
            if (isSave)
            {
                opsResult.Succeed =  await NsDbContext.SaveChangesAsync() > 0;
                opsResult.Message = opsResult.Succeed ? "删除成功" : "删除失败";
            }
            else
            {
                opsResult.Succeed = true;
                opsResult.Message = "已添加到删除队列";
            }
            return opsResult;
        }


        /// <summary>
        ///  保存数据
        /// </summary>
        /// <returns>成功的记录数</returns>
        public virtual async Task<int> SaveChangesAsync()
        {
            return await NsDbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="isSave">是否立即保存</param>
        /// <returns>操作结果
        /// OperationResult.Succeed：操作是否完成，当isSave=false仅表示操作完成并未实际保存到数据库；
        /// OperationResult.Code：无返回值；
        /// OperationResult.Message：操作结果的文本提示；
        /// OperationResult.Data：无返回值。
        /// </returns>
        public virtual async Task<OperationResult> UpdateAsync(T entity, bool isSave = true)
        {
            var opsResult = new OperationResult();
            NsDbContext.Set<T>().Update(entity);
            if (isSave)
            {
                opsResult.Succeed = await NsDbContext.SaveChangesAsync() > 0;
                opsResult.Message = opsResult.Succeed ? "更新成功" : "更新失败";
            }
            else
            {
                opsResult.Succeed = true;
                opsResult.Message = "已添加到更新队列";
            }
            return opsResult;
        }
    }
}
